package com.ym.b2b.payment.controller.bocPay;

import java.io.FileInputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.w3c.dom.Document;

import com.alibaba.fastjson.JSON;
import com.ym.b2b.commons.conf.B2BConstants;
import com.ym.b2b.commons.conf.WebTokenUser;
import com.ym.b2b.commons.controller.BaseController;
import com.ym.b2b.commons.exception.BaseException;
import com.ym.b2b.commons.util.CheckData;
import com.ym.b2b.order.DefaultTradeRequestImpl;
import com.ym.b2b.order.TradeRequest;
import com.ym.b2b.order.dao.EmSOrderConfirmItemDao;
import com.ym.b2b.order.dao.EmSOrderDao;
import com.ym.b2b.order.sqlbean.EmSOrder;
import com.ym.b2b.order.sqlbean.EmSOrderConfirmItem;
import com.ym.b2b.order.vo.OrderInfoVO;
import com.ym.b2b.order.xc.sqlbean.XCReturnModel;
import com.ym.b2b.payment.controller.bocPay.security.Base64;
import com.ym.b2b.payment.controller.bocPay.security.PKCSTool;
import com.ym.b2b.payment.controller.bocPay.system.PaymentEnvironment;
import com.ym.b2b.payment.controller.bocPay.util.DocumentUtil;
import com.ym.b2b.payment.controller.bocPay.util.XmlUtil;
import com.ym.b2b.payment.service.EmSPaymentService;
import com.ym.b2b.payment.sqlbean.EmSPayment;
import com.ym.b2b.payment.vo.PaymentBean;
import com.zc.commons.base.Result;

/**
 * 
 * @ClassName: NB2BPayController
 * @Date 2016年8月19日 上午10:26:06
 * @Modify
 * @CopyRight 珍诚医药在线股份有限公司
 */
@Controller
@RequestMapping("/B2BPay")
public class NB2BPayController  extends BaseController {

	@Resource
	private BOCV1Params boc1Params ;
	
	@Resource
	private TradeRequest defaultTradeRequest;

	@Autowired
	private EmSOrderDao emSOrderDao;
	@Autowired
	private EmSOrderConfirmItemDao emSOrderItemDao;

	@Autowired
	private EmSPaymentService emSPaymentService;
	
	@RequestMapping("getBOCPayInfoForFee.s")
	public ModelAndView getCCBPayInfoForFee(EmSOrder emSOrder, HttpServletRequest request) {
		logger.info("----------进入中行支付接口, 传入参数: \n " + JSON.toJSONString(emSOrder));
    	ModelAndView m = new ModelAndView();
    	try {
            WebTokenUser token = getWebTokenUser(request);
            if (null == token) {
                m.setViewName(B2BConstants.WEB_NOT_LOGIN);
                return m;
            }
            // 组装需要塞入的订单信息
            EmSOrder s = emSOrderDao.searchOrderDetail(emSOrder);
            if (null == s || s.getStatus() >= 20) {
                m.addObject("info", "订单已经支付过了  不能重复提交!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }

            // 填充支付
            PaymentBean emSPaymentBean = new PaymentBean();
            emSPaymentBean.setOrderCode(s.getOrderCode());
            emSPaymentBean.setPaymentRequestIp(CheckData.getIpAddr(request));
            emSPaymentBean.setPaymentMoney(s.getConfirmMoney());
            Result ret = emSPaymentService.doPayBefore(emSPaymentBean);

            if (ret.getCode().equals("100")) {
                m.addObject("info", "订单支付请求 提交失败 请联系管理员!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }
            
            boc1Params.setOrderNo(s.getOrderCode());
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            boc1Params.setOrderTime(sdf.format(sdf2.parse(s.getCreateDateStr())));
            DecimalFormat df=new DecimalFormat("0");	// 金额要保留2位小数
            String orderAmount = df.format(s.getConfirmMoney()*100);
            boc1Params.setAmount(orderAmount);
            DocumentUtil du = new DocumentUtil();
            Map<String, String> map=  du.getRequestMap(boc1Params);
            
            // 从XML中获取固定写死字段
            m.addObject("bocParam", map);
            logger.info("----------发送到支付网站的数据====BOC: \n " + JSON.toJSONString(map));
            m.setViewName("/center/trade/pay/bocpay/post_do");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            m.setViewName(B2BConstants.WEB_ERROR);
        }
    	return m;
    }
	
	@RequestMapping("NB2BQueryOrder.s")
	public ModelAndView NB2BQueryOrder(HttpServletRequest request, EmSOrder emSOrder){

		logger.info("----------进入中行查询接口, 传入参数: \n " + JSON.toJSONString(emSOrder));
    	ModelAndView m = new ModelAndView();
    	try {
            boc1Params.setOrderNo(emSOrder.getOrderCode());
            DocumentUtil du = new DocumentUtil();
            Map<String, String> map=  du.getRequestMapForQuery(boc1Params);
            logger.info("----------发送到中行支付网站的数据====BOC: \n " + JSON.toJSONString(map));
            map.put("action", "http://180.168.146.72/PGWPortal/NB2BQueryTrans.do");
            // 从XML中获取固定写死字段
            m.addObject("bocParam", map);
            logger.info("----------发送到中行支付网站的数据====BOC: \n " + JSON.toJSONString(map));
            m.setViewName("/center/trade/pay/bocpay/post_do");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            m.setViewName(B2BConstants.WEB_ERROR);
        }
    	return m;
    
	}
	
	  // 银行返回recviceBOCPay.s
    @RequestMapping("recviceBOCPay.s")
	public void recviceCCBPay(HttpServletRequest request, HttpServletResponse response) {
		try {
			logger.info("----------		接收支付网站回调参数====BOC	----------");

			String message = request.getParameter("message");
            String signature = request.getParameter("signature");
            logger.info("[message]=[" + message + "] [signature]=[" + signature + "]");
/*            message="PD94bWwgdmVyc2lvbj"
					+"0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+PHJlc3BvbnNlPjxoZWFkPg0KPHJlc3BvbnNlQ29kZT5PSzwvcmVzcG9uc2VDb2RlPg0KPHJlc3BvbnNlSW5mbz"
					+"7miJDlip88L3Jlc3BvbnNlSW5mbz4NCjwvaGVhZD4NCjxib2R5Pg0KPG1lcmNoYW50Tm8+NzI5ODwvbWVyY2hhbnRObz4NCjxvcmRlck5vPjE2MTIxNTA4NT"
					+"EzODEwMzc3NjkyPC9vcmRlck5vPg0KPG9yZGVyU2VxPjExNjA1MDMzMzwvb3JkZXJTZXE+DQo8dHJhbnNTZXE+NjYzMDUyNDA8L3RyYW5zU2VxPg0KPGN1cn"
					+"JlbmN5PjE1NjwvY3VycmVuY3k+DQo8YW1vdW50PjQwMDwvYW1vdW50Pg0KPHRyYW5UeXBlPjAxPC90cmFuVHlwZT4NCjxwYXlDYXRhbG9nPjE8L3BheUNhdG"
					+"Fsb2c+DQo8ZmVlQW1vdW50PjA8L2ZlZUFtb3VudD4NCjx0cmFuU3RhdHVzPjE8L3RyYW5TdGF0dXM+DQo8dHJhblRpbWU+MjAxNjEyMTUwODU1MjI8L3RyYW"
					+"5UaW1lPg0KPHBheWVySWJrbnVtPioqKio8L3BheWVySWJrbnVtPg0KPHBheWVyQWN0TnVtPioqKio8L3BheWVyQWN0TnVtPg0KPHBheWVyQWN0TmFtPioqKi"
					+"o8L3BheWVyQWN0TmFtPg0KPHBheWVyQm5rRXBzYnRwPjwvcGF5ZXJCbmtFcHNidHA+DQo8cGF5ZXJCbmtOYW0+PC9wYXllckJua05hbT4NCjwvYm9keT4NCj"
					+"wvcmVzcG9uc2U+";
            signature = "MIID0QYJKoZIhvcNAQcCoIIDwjCCA74CAQMxCTAHBgUrDgMCGjALBgkqhkiG9w0BBwGgggJsMIICaDCCAdGgAwIBAgI"+
					"QfUcmGU5Dp0r66SIzTak6lDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJDTjEWMBQGA1UEChMNQkFOSyBPRiBDSElOQTEQMA4GA1UECBMHQkVJSklORzE"+
					"QMA4GA1UEBxMHQkVJSklORzEPMA0GA1UEAxMGQk9DIENBMB4XDTExMDYxODEwMjYyNFoXDTIxMDQyNjEwMjYyNFowRzELMAkGA1UEBhMCQ04xFjAUBgNVBAo"+
					"TDUJBTksgT0YgQ0hJTkExDTALBgNVBAsTBFRFU1QxETAPBgNVBAMeCG1Li9VVRmI3MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDRfqNZjaGwButIJv"+
					"XBg2zrquSiyrERf447LX486K89akHYmOYmwrt54JNlR8QH9yVe23g8Ozrlo8SGsZ7bFojmhYbo0pcUu3cnn5OLjsB1rhTqGRiBv7HF3I1O+DS3UjNKbY+Nkn"+
					"3TLG6s3EPJKr1ezGz6iVvM7ZXn5mn3WKSYQIDAQABo0IwQDAfBgNVHSMEGDAWgBR48bbzvcpEDXwv6NI2yP4GsMD5nzAdBgNVHQ4EFgQUuh0z/bgWTLx86on"+
					"WP4ae5vYcdM0wDQYJKoZIhvcNAQEFBQADgYEAMi8mBiqKYmNH0mkzP3xJYP9yUaznL/MazTa+bXcputVuOHd1Ied8w/uXDoUJ0H2BBOnekHokYnDYt5MId5q"+
					"/QV9Ph+7gauEkPRqvfYJNxLXS3uBDCGWxNNUj8ylYlBNgPu3sH3x4BcuYuFcHqAfTJqaWhdUT49KRn7RaendPnVgxggEvMIIBKwIBAzBuMFoxCzAJBgNVBAY"+
					"TAkNOMRYwFAYDVQQKEw1CQU5LIE9GIENISU5BMRAwDgYDVQQIEwdCRUlKSU5HMRAwDgYDVQQHEwdCRUlKSU5HMQ8wDQYDVQQDEwZCT0MgQ0ECEH1HJhlOQ6d"+
					"K+ukiM02pOpQwBwYFKw4DAhowCwYJKoZIhvcNAQEBBIGAg2IvX9AcTKYjnD9JKWAD/W7jSkmqOIcTSQ40kpZJStJ6MFbuVS8b0D1FkDQDvGmlvZ/IJbtCDyl"+
					"rvaJyZYaXpU/8mH0Ea+oTj1zqB63D4/IvWA8kjIfhGGwwwoJbQF6o3CUTXQj1w5t+ZfFE+qRZkEN5EnZAkoeKQqcIjkVYlQGhHTAbBgFRMRYEFL54c8+sPoh"+
					"flCsSaC9CzghS8FFI";*/

            //对返回数据进行签名验证
            String plainText = new String(Base64.decode(message), "UTF-8");
            logger.info("[base64解码后message]=[" + plainText + "]");
            
            //获取验签根证书，对P7验签使用二级根证书
            InputStream fis4cer = new FileInputStream(boc1Params.getVerifyCerFile());
            PKCSTool tool = PKCSTool.getVerifier(fis4cer,null);
            //验证签名,验证失败将抛出异常
            tool.p7Verify(signature, plainText.getBytes("UTF-8"));
            logger.info("[VERIFY OK]");
            
            //获取返回数据
            Document document = XmlUtil.createDocument(plainText);
            //获取返回码,商户根据业务逻辑处理
            String responseCode = XmlUtil.getNodeText(document, "responseCode");
			if ("OK".equals(responseCode)
					&& ("1".equals(XmlUtil.getNodeText(document, "tranStatus")) || "4"
							.equals(XmlUtil.getNodeText(document, "tranStatus")))) { // 交易结果判断

				// 更新订单状态 和 支付表数据
				SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
				EmSOrder order = new EmSOrder();
				order.setOrderCode(XmlUtil.getNodeText(document, "orderNo"));		//	订单号
				order.setFeeDate(sf.format(sf.parse(XmlUtil.getNodeText(document, "tranTime"))));
				order.setTranSerialNo(XmlUtil.getNodeText(document, "transSeq")); // 网关生成的交易流水
				order.setFeeAmount(Double.parseDouble(XmlUtil.getNodeText(document, "amount"))/ 100);
				order.setOrderType(1); // 在线付款
				
				String payCatalog = XmlUtil.getNodeText(document, "payCatalog");	// 支付方式1:中行网银支付2:跨行支付
				
				// ========================================= ERP相关处理start	=========================================
				// 在application_config.xml中控制判断什么时候对接ERP下订单 ,false 则在支付后下单,ture则在确认时下单
				if (!DefaultTradeRequestImpl.isBooking()) {
					// 根据orderCode查出订单信息,订单产品详情,并组装成ERP接口所需model
					EmSOrder orderForERP = emSOrderDao.searchOrderDetail(order);
					EmSOrderConfirmItem item = new EmSOrderConfirmItem();
					item.setOrderCode(XmlUtil.getNodeText(document, "orderNo").substring(0, 14));
					List<EmSOrderConfirmItem> listItem = emSOrderItemDao.searchEmSOrderConfirmItem(item);
					OrderInfoVO vo = makeOrderInfo(orderForERP, listItem);

					// 调用ERP create接口
					Result erpResult = defaultTradeRequest.bookingErpOrder(vo,null);
					if (!"200".equals(erpResult.getCode())) {
						logger.error("ERP下单失败:" + erpResult.getResult());
						throw new BaseException("ERP下单失败:"
								+ erpResult.getResult());
					}

					// *** ERP下单成功：更新erp系统的内部单据号 *******//*
					XCReturnModel xcReturnModel = (XCReturnModel) erpResult
							.getData().get("orderRet");
					if (null != xcReturnModel
							&& !"".equals(xcReturnModel.getOrderCode())) {
						String returnCode = xcReturnModel.getOrderCode();
						order.setOrderCodeErp(returnCode.substring(returnCode
								.indexOf("-") + 1));
					}
				} else {
					// 根据orderCode查出订单信息,订单产品详情,并组装成ERP接口所需model
					EmSOrder orderForERP = emSOrderDao.searchOrderDetail(order);
					EmSOrderConfirmItem item = new EmSOrderConfirmItem();
					item.setOrderCode(XmlUtil.getNodeText(document, "orderNo").substring(0, 14));
					List<EmSOrderConfirmItem> listItem = emSOrderItemDao.searchEmSOrderConfirmItem(item);
					OrderInfoVO vo = makeOrderInfo(orderForERP, listItem);

					// 调用ERP create接口
					defaultTradeRequest.updateOrder(vo,listItem);
				}
				// =========================================	ERP相关处理end	=========================================
				order.setStatus(Double.parseDouble("20")); // 已付款
				emSOrderDao.updateEmSOrder(order);

				EmSPayment payment = new EmSPayment();
				payment.setOrderCode(XmlUtil.getNodeText(document, "orderNo").substring(0, 14));
				payment.setPaymentFrom("PC");
				payment.setPaymentMedthod("中行");
				payment.setPaymentMoney(Double.parseDouble(XmlUtil.getNodeText(document, "amount")) / 100);
				payment.setPaymentCompleteDate(sf.parse(XmlUtil.getNodeText(document, "tranTime")));
				payment.setPaymentStatus(1);
				payment.setDealFlag(1);

				emSPaymentService.updateEmSPayment(payment);
				System.out.println("商户订单处理完成");
			} else {
				System.out.println("商户订单处理失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e);
		}
	}

    private OrderInfoVO makeOrderInfo(EmSOrder orderForERP,List<EmSOrderConfirmItem> list){
    	OrderInfoVO vo = new OrderInfoVO();
    	vo.setOrderCode(orderForERP.getOrderCode());
    	vo.setBuyerCode(orderForERP.getBuyerCode());
    	WebTokenUser user = new WebTokenUser();
    	user.setBuyerCode(orderForERP.getBuyerCode());
    	vo.setErpCode(orderForERP.getOrderCodeErp());
    	vo.setUser(user);
    	vo.setSalesman(orderForERP.getSalesman());
    	vo.setEmSOrderConfirmItemList(list);
    	return vo;
    }
}
